package app.itgungnir.compose.wan.widgets

import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Tour
import androidx.compose.material.icons.outlined.FavoriteBorder
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import app.itgungnir.compose.wan.business.main.home.HomeArticle
import app.itgungnir.compose.wan.theme.WanComposePreviewTheme
import app.itgungnir.compose.wan.theme.paletteColors
import app.itgungnir.compose.wan.utils.WanDatabase
import com.google.accompanist.flowlayout.FlowRow

@Composable
fun WanFab(icon: ImageVector, onClick: () -> Unit) {
    FloatingActionButton(onClick = { onClick.invoke() }) {
        Icon(imageVector = icon, contentDescription = "", tint = MaterialTheme.colors.onSecondary)
    }
}

@Composable
fun WanTagButton(
    modifier: Modifier = Modifier,
    text: String? = null,
    randomColor: Boolean = false,
    color: Color = MaterialTheme.colors.primary,
    style: TextStyle = MaterialTheme.typography.overline,
    loadingState: State<Boolean> = mutableStateOf(false),
    onClick: (() -> Unit)? = null
) {
    text?.takeIf { it.isNotEmpty() }?.let {
        val shownColor = when (randomColor) {
            true -> paletteColors.random().lightPrimaryColor
            else -> color
        }
        val enabled = !loadingState.value
        Text(
            modifier = modifier
                .clip(shape = RoundedCornerShape(size = 5.dp))
                .background(color = shownColor.copy(alpha = if (enabled) 0.2F else 0.05F))
                .then(if (onClick != null && enabled) Modifier.clickable { onClick.invoke() } else Modifier)
                .padding(horizontal = 5.dp, vertical = 2.dp),
            text = it,
            color = shownColor.copy(alpha = if (enabled) 1F else 0.6F),
            style = style,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
    }
}

@Composable
fun WanTextButton(
    modifier: Modifier = Modifier,
    icon: ImageVector? = null,
    text: String? = null,
    color: Color = MaterialTheme.colors.primary,
    style: TextStyle = MaterialTheme.typography.button,
    loadingState: State<Boolean> = mutableStateOf(false),
    onClick: () -> Unit = {}
) {
    text?.takeIf { it.isNotEmpty() }?.let {
        TextButton(modifier = modifier, onClick = { onClick.invoke() }, enabled = !loadingState.value) {
            icon?.let {
                Icon(imageVector = icon, contentDescription = "", tint = color)
            }
            Text(
                text = it,
                color = color,
                style = style,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        }
    }
}

@Composable
fun WanIconButton(
    modifier: Modifier = Modifier,
    icon: ImageVector,
    color: Color = MaterialTheme.colors.onPrimary,
    loadingState: State<Boolean> = mutableStateOf(false),
    onClick: () -> Unit = {}
) {
    IconButton(modifier = modifier, onClick = { onClick.invoke() }, enabled = !loadingState.value) {
        Icon(imageVector = icon, contentDescription = "", tint = color)
    }
}

@Composable
fun WanButton(
    modifier: Modifier = Modifier,
    text: String? = null,
    style: TextStyle = MaterialTheme.typography.button,
    loadingState: State<Boolean> = mutableStateOf(false),
    onClick: () -> Unit = {}
) {
    text?.takeIf { it.isNotEmpty() }?.let {
        Button(modifier = modifier, onClick = { onClick.invoke() }, enabled = !loadingState.value) {
            if (loadingState.value) {
                CircularProgressIndicator(
                    modifier = Modifier.size(15.dp),
                    color = MaterialTheme.colors.onPrimary,
                    strokeWidth = 2.dp
                )
            } else {
                Text(text = it, color = MaterialTheme.colors.onPrimary, style = style)
            }
        }
    }
}

@Composable
fun WanCollectButton(
    modifier: Modifier = Modifier,
    item: HomeArticle,
    loadingState: State<Boolean> = mutableStateOf(false),
    onClick: (Boolean) -> Unit
) {
    val collectCount = WanDatabase.dao.queryHomeArticleCollectCount(item.id).collectAsState(null)
    val hasCollected = (collectCount.value ?: 0) > 0
    WanIconButton(
        modifier = modifier,
        icon = when (hasCollected) {
            true -> Icons.Filled.Favorite
            else -> Icons.Outlined.FavoriteBorder
        },
        color = when (hasCollected) {
            true -> MaterialTheme.colors.primary
            else -> MaterialTheme.colors.onBackground
        },
        onClick = { onClick.invoke(hasCollected) },
        loadingState = loadingState
    )
}

@Composable
fun <T : Any> WanRadioButtonGroup(
    modifier: Modifier = Modifier,
    icon: ImageVector = Icons.Filled.Tour,
    iconTintColor: Color = MaterialTheme.colors.onBackground,
    selectedValueState: MutableState<T?> = mutableStateOf(null),
    choicePairs: List<Pair<String, T?>> = listOf(),
    loadingState: State<Boolean> = mutableStateOf(false)
) {
    choicePairs.takeIf { it.isNotEmpty() }?.let { names ->
        Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
            Icon(imageVector = icon, contentDescription = "", tint = iconTintColor)
            Spacer(modifier = Modifier.width(15.dp))
            FlowRow(modifier = Modifier.fillMaxWidth()) {
                names.forEach { choice ->
                    Row(
                        modifier = Modifier
                            .selectable(
                                selected = selectedValueState.value == choice.second,
                                onClick = { selectedValueState.value = choice.second },
                                enabled = !loadingState.value
                            )
                            .padding(top = 2.dp, bottom = 2.dp, end = 10.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        RadioButton(
                            selected = selectedValueState.value == choice.second,
                            onClick = { selectedValueState.value = choice.second },
                            enabled = !loadingState.value
                        )
                        WanDescription(content = choice.first)
                    }
                }
            }
        }
    }
}

@Preview(name = "WanButton light mode", showBackground = true)
@Preview(name = "WanButton dark mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true)
@Composable
private fun WanButtonPreview() {
    WanComposePreviewTheme {
        Column(modifier = Modifier.fillMaxWidth()) {
            WanFab(icon = Icons.Filled.Add) {}
            WanTagButton(text = "Tag按钮")
            WanTextButton(text = "Text按钮")
            WanTextButton(icon = Icons.Filled.Add, text = "带按钮的Text按钮")
            WanIconButton(icon = Icons.Filled.Add)
            WanButton(text = "普通按钮")
            val selectedChoiceState = remember { mutableStateOf<Int?>(null) }
            WanRadioButtonGroup(
                selectedValueState = selectedChoiceState,
                choicePairs = listOf("选项0001" to 1, "选项2" to 2, "选项003" to 3, "选项0000004" to 4, "选项05" to 5)
            )
            WanDescription(content = "选中项：${selectedChoiceState.value}")
        }
    }
}
